home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 4.iso
/
src
/
apps
/
ibrowse
/
ibrowse_sgi.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-01
|
8KB
|
268 lines
/*
* Copyright 1993, 1994, Silicon Graphics, Inc.
* All Rights Reserved.
*
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
* the contents of this file may not be disclosed to third parties, copied or
* duplicated in any form, in whole or in part, without the prior written
* permission of Silicon Graphics, Inc.
*
* RESTRICTED RIGHTS LEGEND:
* Use, duplication or disclosure by the Government is subject to restrictions
* as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
* and Computer Software clause at DFARS 252.227-7013, and/or in similar or
* successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
* rights reserved under the Copyright Laws of the United States.
*/
/*
ibrowse_sgi.c - Support for identifying and iconifying SGI format images.
Tim Heidmann, Paul Haeberli, Silicon Graphics
Version 1.2.2
November 29, 1993
copyright 1993, Silicon Graphics
*/
#include <gl.h>
#include <gl/image.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <limits.h>
#include <malloc.h>
#include "ibrowse.h"
#define IPASTE_MARGIN 50
unsigned long *myColormap_SGI = NULL;
void GetColormap_SGI();
int
Check_SGI(struct iconDirStruct *ids, int fd) {
/* Check for SGI image type file.
If it is an image, set xsize, ysize, zsize.
Return TRUE iff it is an SGI format image file. */
int len;
IMAGE ibuf;
len = read(fd, &ibuf, sizeof(ibuf));
if ((len == (signed int) sizeof(ibuf)) && (ibuf.imagic == IMAGIC)) {
ids->xsize = ibuf.xsize;
ids->ysize = ibuf.ysize;
ids->zsize = ibuf.zsize;
ids->subType = ibuf.colormap << 16 | ibuf.type;
return TRUE;
} else
return FALSE;
}
/*
* Read image file and subsample into memory slot.
*/
#define PACK_RGBA_08(r, g, b, a) ((unsigned long) \
((a)<<24 | (b)<<16 | (g)<<8 | (r)))
#define PACK_RGBA_16(r, g, b, a) ((unsigned long) \
(((a)&0xff00)<<16 | ((b)&0xff00)<<8 | ((g)&0xff00) | ((r)&0xff00)>>8))
static short *rbuf = NULL, *gbuf, *bbuf, *abuf;
static int rowlen = 0;
int
Iconify_SGI(struct iconDirStruct *ids, unsigned long *ip) {
IMAGE *f;
short r, g, b;
char name_buf[PATH_MAX];
int irow, isrcrow, icol, startrow, endrow, startcol, endcol, isrccol;
int fileLen;
float srcrow, srccol, xsrcinc, ysrcinc;
if (ids->xsize <= 0 || ids->ysize <= 0 || ids->zsize <= 0) return TRUE;
/* Read sparse rows of the image to make an icon */
sprintf(name_buf, "%s/%s", theDirName, ids->name);
if ((f = iopen(name_buf, "r")) == NULL) return FALSE;
/* Calculate sampling parameters */
xsrcinc = f->xsize / (float) ids->ixsize;
ysrcinc = f->ysize / (float) ids->iysize;
/* Allocate row buffers */
if(f->xsize>rowlen) {
if(rbuf) {
free(rbuf);
free(gbuf);
free(bbuf);
free(abuf);
}
rowlen = f->xsize;
rbuf = (short *)malloc(rowlen*sizeof(short));
gbuf = (short *)malloc(rowlen*sizeof(short));
bbuf = (short *)malloc(rowlen*sizeof(short));
abuf = (short *)malloc(rowlen*sizeof(short));
}
/* Point-sample the image */
for (irow = 0, srcrow = 0.5 * ysrcinc; irow < ids->iysize;
irow++, srcrow += ysrcinc) {
/* Read each component */
isrcrow = (int) srcrow;
getrow(f, rbuf, isrcrow, 0);
if (f->zsize >= 3) {
getrow(f, gbuf, isrcrow, 1);
getrow(f, bbuf, isrcrow, 2);
if (f->zsize > 3)
getrow(f, abuf, isrcrow, 3);
}
/*
* Decode and pack components into ABGR word.
*/
if (ids->subType>>16 == CM_SCREEN) {
/* Colormap image. Map the first channel with current map */
if (myColormap_SGI == NULL) GetColormap_SGI();
for (icol = 0, srccol = 0.5 * xsrcinc;
icol < ids->ixsize; icol++, srccol += xsrcinc, ip++) {
isrccol = (int) srccol;
/* Wrap indices > 255 around, so at least we see some detail */
*ip = myColormap_SGI[rbuf[isrccol] % 256] | 0xff000000;
}
} else if ((ids->subType & BPPMASK) == 2) {
/* 2 bytes per pixel NORMAL image */
for (icol = 0, srccol = 0.5 * xsrcinc;
icol < ids->ixsize; icol++, srccol += xsrcinc, ip++) {
isrccol = (int) srccol;
/* The following statements should probably use the PACK_RGBA_16 macro
* to convert 16-bit channels to 8-bit channels, but the SGI video products
* save 16-bit channels in the range 0-255, so use PACK_RGBA_08.
*/
if (f->zsize > 3)
*ip = PACK_RGBA_08(rbuf[isrccol], gbuf[isrccol],
bbuf[isrccol], abuf[isrccol]);
else if (f->zsize == 3)
*ip = PACK_RGBA_08(rbuf[isrccol], gbuf[isrccol],
bbuf[isrccol], 0xff);
else
*ip = PACK_RGBA_08(rbuf[isrccol], rbuf[isrccol],
rbuf[isrccol], 0xff);
}
} else {
/* 1 byte per pixel NORMAL image */
for (icol = 0, srccol = 0.5 * xsrcinc;
icol < ids->ixsize; icol++, srccol += xsrcinc, ip++) {
isrccol = (int) srccol;
if (f->zsize > 3)
*ip = PACK_RGBA_08(rbuf[isrccol], gbuf[isrccol],
bbuf[isrccol], abuf[isrccol]);
else if (f->zsize == 3)
*ip = PACK_RGBA_08(rbuf[isrccol], gbuf[isrccol],
bbuf[isrccol], 0xff);
else
*ip = PACK_RGBA_08(rbuf[isrccol], rbuf[isrccol],
rbuf[isrccol], 0xff);
}
}
}
iclose(f);
return TRUE;
}
char *
Info_SGI(struct iconDirStruct *ids, char *buf) {
int colormap;
colormap = ids->subType >> 16;
sprintf(buf, "SGI format %s, %s, %d %s/pixel",
(colormap == CM_NORMAL) ?
((ids->zsize >= 3) ? "RGB image" :
"B/W image") :
(colormap == CM_DITHERED) ? "3:3:2 image" :
(colormap == CM_SCREEN) ? "colorindex image" :
(colormap == CM_COLORMAP) ? "color map" :
"",
((ids->subType & TYPEMASK) == 0) ?
"Verbatim" :
"RLE",
(ids->subType & BPPMASK),
((ids->subType & BPPMASK) == 1) ?
"byte" :
"bytes"
);
return buf;
}
void
Open_SGI(struct iconDirStruct *ids) {
char buf[PATH_MAX+64];
char *cmd;
/* What to do on double-click of icon... */
if ((cmd = getenv("IBROWSE_SGI_OPEN_CMD")) != NULL)
/* Invoke the command in the environment variable. */
;
else if (useIconFiles)
/* Browsing from icon files. Don't try to open an image file. */
return;
else if (modKeys & SHIFTKEYBIT)
/* Shift-open, always ipaste */
sprintf(cmd = buf, "/usr/sbin/ipaste %s/%s", theDirName, ids->name);
else if (modKeys & CTRLKEYBIT)
/* Ctrl-open, always scope */
sprintf(cmd = buf, "/usr/sbin/scope %s/%s", theDirName, ids->name);
else
/* Default action - "ipaste" small images,
* "scope" images too large to fit comfortably on the screen.
*/
sprintf(cmd = buf, "/usr/sbin/%s %s/%s",
(ids->xsize > getgdesc(GD_XPMAX) - IPASTE_MARGIN ||
ids->ysize > getgdesc(GD_YPMAX) - IPASTE_MARGIN) ?
"scope" : "ipaste",
theDirName, ids->name);
system(cmd);
}
/* Low 16 slots of SGI default colormap */
unsigned long lo16_SGI[] = {
0xff000000, 0xff0000ff, 0xff00ff00, 0xff00ffff,
0xffff0000, 0xffff00ff, 0xffffff00, 0xffffffff,
0xff555555, 0xff7171c6, 0xff71c671, 0xff388e8e,
0xffc67171, 0xff8e388e, 0xff8e8e38, 0xffaaaaaa
};
void
GetColormap_SGI() {
int i, r, g, b;
myColormap_SGI = (unsigned long *) malloc(256 * sizeof(unsigned long));
/* Low 16 slots from a constant table */
for (i = 0; i <= 15; i++) myColormap_SGI[i] = lo16_SGI[i];
/* 16 through 31 are all black */
for (i = 16; i <= 31; i++) myColormap_SGI[i] = 0;
/* 32 through 55 are a blackish to whiteish ramp */
for (i = 32; i <= 55; i++) {
r = g = b = (i - 31) * 255 / (56 - 31);
myColormap_SGI[i] = PACK_RGBA_08(r, g, b, 0xff);
}
/* 56 through 255 are BRG 5x5x8 table */
for (i = 56; i <=255; i++) {
g = (i - 56) % 8;
r = (i - 56) / 8 % 5;
b = (i - 56) / 40;
myColormap_SGI[i] = PACK_RGBA_08(r*255/4, g*255/7, b*255/4, 0xff);
}
}